<?php
/**
 * Created by PhpStorm.
 * User: Echa
 * Date: 2016/9/7
 * Time: 14:01
 */
namespace SDXApi\Model;
use Think\Model;
use Think\Template\Driver\Mobile;

class GoodsstorageModel extends Model
{
    protected $tableName = 'goods_storage';
    
    /*
     * 根据仓库编号和对应商品编号查询仓库商品数据
     * */
    public function get_warehous_goods($wid=0,$goods_id=0,$is_add_check=0){
        $where=array('wid'=>$wid,'goods_id'=>$goods_id);
        $res=$this->where($where)->find();
        $online_safe_inventory=M("goods")->where(array("goods_id"=>$goods_id))->getField("online_safe_inventory");
        /* $where=array('goods_id'=>$goods_id);
        $res=M("goods_wid_".$wid)->where($where)->find(); */
        if($res){
            $goods_practical_num = $res['practical_num'];
            if($is_add_check){
                if($goods_practical_num-C('rest_goods_number')-$online_safe_inventory>0){
                    $res['practical_num'] = intval($goods_practical_num-C('rest_goods_number')-$online_safe_inventory);
                }else{
                    $res['practical_num']=0;
                }
            }
            //获取实际库存缓存
            $cache_goods_practical_num = get_goods_practical_num_cache($goods_id,$wid,$goods_practical_num);
            
            return $res;
        }else{
            return false;
        }
    }
    
    /*
     * 检查对应仓库库存商品数是否为0
     * */
    public function check_warehous_goods($wid=0,$goods_id=0,$num=1,$is_add_check=0){
        $where=array('wid'=>$wid,'goods_id'=>$goods_id);
        $practical_num=$this->where($where)->getField('practical_num');
        //获取实际库存缓存
        $cache_goods_practical_num = get_goods_practical_num_cache($goods_id,$wid,$practical_num);
        /* $where=array('goods_id'=>$goods_id);
        $practical_num=M("goods_wid_".$wid)->where($where)->getField('goods_number'); */
        if($is_add_check){
            if($practical_num-C('rest_goods_number')>0){
                $practical_num = intval($practical_num-C('rest_goods_number'));
            }else{
                $practical_num=0;
            }
        }
        if($practical_num>=$num){
            return true;
        }else{
            return false;
        }
    }
    
    /*
     * 检查对应仓库库存商品数是否为0
     * */
    public function check_warehous_goods_return($wid=0,$goods_id=0,$num=1){
        $where=array('wid'=>$wid,'goods_id'=>$goods_id);
        $practical_num=$this->where($where)->getField('practical_num');
        //获取实际库存缓存
        $cache_goods_practical_num = get_goods_practical_num_cache($goods_id,$wid,$practical_num);
        if($practical_num>=$num){
            return false;
        }else{
            return $practical_num;
        }
    }
    
    /*
     * 减去实际库存
     * */
    public function save_theactual_goods($wid=0,$goods_id=0,$num=1,$is_offline=false){
        $goods_storage=$this->get_warehous_goods($wid,$goods_id);
        if($goods_storage){
            //获取实际库存缓存
            $cache_goods_practical_num = get_goods_practical_num_cache($goods_id,$wid,$goods_storage['practical_num']);
            if($is_offline){
                //获取队列库存缓存
                $cache_queue_goods_stock = get_queue_goods_stock($goods_id,$wid);
            }
            $where=array('wid'=>$wid,'goods_id'=>$goods_id);
            $data=array(
                'practical_num'=>$goods_storage['practical_num']-$num,
                'freeze_num'=>$goods_storage['freeze_num']+$num,
            );
            $id=$this->where($where)->save($data);
            if($id){
                //更新实际库存缓存
                set_goods_practical_num_cache($goods_id,$wid,$cache_goods_practical_num-$num);
                if($is_offline){
                    set_queue_goods_stock($goods_id,$wid,$cache_queue_goods_stock-$num);
                }
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        } 
    }
    
    /*
     * 减去冻结库存数
     * */
    public function save_freeze_theactual_goods($wid=0,$goods_id=0,$num=1){
        $goods_storage=$this->get_warehous_goods($wid,$goods_id);
        if($goods_storage){
            $where=array('wid'=>$wid,'goods_id'=>$goods_id);
            $data=array(
                'freeze_num'=>$goods_storage['freeze_num']-$num,
            );
            $id=$this->where($where)->save($data);
            if($id){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    
    /*
     * 检查是否该商品是否是预售商品,若是预售商品，则返回1,否则是现售返回0;
     * */
    public function check_whether_presell($goods_id=0,$wid=0,$is_add_check=0){
       $rs = $this->get_warehous_goods($wid, $goods_id);
        if($is_add_check){
            if($rs['practical_num']>0){
                $rs['practical_num'] = intval($rs['practical_num']);
            }else{
                $rs['practical_num'] = 0;
            }
        }

        if($rs['practical_num']>0){
            return 0;
        }else{
            return 1;
        }
    }
    
    /*
     * 系统冻结盘点
     * */
    public function system_freeze_pandian($goods_id=0,$wid=0){
        ini_set('max_execution_time', '0');
        set_time_limit(0);
        //查询未确认收货的订单现售商品,并且是订单不包含无效订单、取消订单、全部退款
        //$order_goodswhere='oi.wid!=0 AND og.is_presell=0 AND oi.shipping_status in(0,1,3) AND  (oi.order_status NOT IN (2,3,4))  AND oi.pay_status!=4 ';
        $order_goodswhere='oi.wid!=0 AND (og.is_presell=0 or (og.is_presell=1 and og.buckle_inventory=1)) AND oi.shipping_status in(0,1,3,5) AND  (oi.order_status NOT IN (2,3,4))  AND oi.pay_status!=4 ';
        if($goods_id && $wid){
            $order_goodswhere.=' and og.goods_id='.$goods_id.' and oi.wid='.$wid;
            
        }
        $order_goods=M('order_info')->alias('oi')
                    ->field('og.goods_id,og.goods_sn,og.goods_name,og.goods_number,oi.wid,og.order_id,oi.order_status')  
                    ->join(C ( 'DB_PREFIX' ) .'order_goods as og on oi.order_id=og.order_id')
                    ->where($order_goodswhere)
                    ->select();
        //查询日常调仓状态未变为"货品到达"-来源仓商品
        $out_the_warehouse_goodswhere='twr.the_warehousecause=1 AND twr.the_warehouse_status IN(1,2)';
        if($goods_id && $wid){
            $out_the_warehouse_goodswhere.=' AND twr.callout_wid='.$wid.' AND twgr.goods_id='.$goods_id;
        }
        $out_the_warehouse_goods=M('the_warehouse_record')->alias('twr')
                                ->field('twgr.goods_id,twgr.goods_sn,twgr.goods_name,twgr.the_warehouse_num,twr.callout_wid,twr.batch_sn')  
                                ->join(C ( 'DB_PREFIX' ) .'the_warehouse_goods_record as twgr ON twr.id=twgr.twid')
                                ->where($out_the_warehouse_goodswhere)
                                ->select();
        //查询日常调仓状态为"货品到达"-目标仓商品
        $in_the_warehouse_goodswhere='twr.the_warehousecause=1 AND twr.the_warehouse_status =3';
        if($goods_id && $wid){
            $in_the_warehouse_goodswhere.=' AND twr.callin_wid='.$wid.' AND twgr.goods_id='.$goods_id;
        }
        $in_the_warehouse_goods=M('the_warehouse_record')->alias('twr')
                                ->field('twgr.goods_id,twgr.goods_sn,twgr.goods_name,twgr.the_warehouse_num,twr.callin_wid,twr.batch_sn')  
                                ->join(C ( 'DB_PREFIX' ) .'the_warehouse_goods_record as twgr ON twr.id=twgr.twid')
                                ->where($in_the_warehouse_goodswhere)
                                ->select();
        $update_goods_storage_arr=array(); // 记录需要系统冻结盘点的商品
        if($order_goods){
            $refund_detail_mod=M('refund_detail');
            foreach ($order_goods as $key=>$val){
                $groudstr=$val['goods_id'].'-'.$val['wid'];
                $update_goods_storage_arr[$groudstr]['goods_id']=$val['goods_id'];
                $update_goods_storage_arr[$groudstr]['goods_sn']=$val['goods_sn'];
                $update_goods_storage_arr[$groudstr]['goods_name']=$val['goods_name'];
                $update_goods_storage_arr[$groudstr]['wid']=$val['wid'];
                $rddata=$refund_detail_mod->field('goods_id,SUM(refund_number) as refund_number')->where(array('order_id'=>$val['order_id'],'goods_id'=>$val['goods_id']))->find();
                if($rddata['refund_number']>0){
                         $val['goods_number']=$val['goods_number']-ceil($rddata['refund_number']);//需要盘点数=购买数量-退款数量
                }
                if($update_goods_storage_arr[$groudstr]['goods_number_sum']){
                         $update_goods_storage_arr[$groudstr]['goods_number_sum']=$update_goods_storage_arr[$groudstr]['goods_number_sum']+$val['goods_number'];
                }else{
                    $update_goods_storage_arr[$groudstr]['goods_number_sum']=$val['goods_number'];
                }
                if( $update_goods_storage_arr[$groudstr]['order_id_str']){
                    $update_goods_storage_arr[$groudstr]['order_id_str']=$update_goods_storage_arr[$groudstr]['order_id_str'].$val['order_id'].',';
                }else{
                    $update_goods_storage_arr[$groudstr]['order_id_str']=$val['order_id'].',';
                }
            }
        }
        
        if($out_the_warehouse_goods){
             foreach ($out_the_warehouse_goods as $k=>$v){
                  $groudstr=$v['goods_id'].'-'.$v['callout_wid'];
                  $update_goods_storage_arr[$groudstr]['goods_id']=$v['goods_id'];
                  $update_goods_storage_arr[$groudstr]['goods_sn']=$v['goods_sn'];
                  $update_goods_storage_arr[$groudstr]['goods_name']=$v['goods_name'];
                  $update_goods_storage_arr[$groudstr]['wid']=$v['callout_wid'];
                  if($update_goods_storage_arr[$groudstr]['goods_number_sum']){
                      $update_goods_storage_arr[$groudstr]['goods_number_sum']=$update_goods_storage_arr[$groudstr]['goods_number_sum']+$v['the_warehouse_num'];
                  }else{
                      $update_goods_storage_arr[$groudstr]['goods_number_sum']=$v['the_warehouse_num'];
                  }                  
                if( $update_goods_storage_arr[$groudstr]['order_id_str']){
                    $update_goods_storage_arr[$groudstr]['order_id_str']=$update_goods_storage_arr[$groudstr]['order_id_str'].$val['batch_sn'].',';
                }else{
                    $update_goods_storage_arr[$groudstr]['order_id_str']=$val['batch_sn'].',';
                }
             }
        }
        
        if($in_the_warehouse_goods){
             foreach ($in_the_warehouse_goods as $k1=>$v1){
                 $groudstr=$v1['goods_id'].'-'.$v1['callin_wid'];
                 $update_goods_storage_arr[$groudstr]['goods_id']=$v1['goods_id'];
                 $update_goods_storage_arr[$groudstr]['goods_sn']=$v1['goods_sn'];
                 $update_goods_storage_arr[$groudstr]['goods_name']=$v1['goods_name'];
                 $update_goods_storage_arr[$groudstr]['wid']=$v1['callin_wid'];
                 if($update_goods_storage_arr[$groudstr]['goods_number_sum']){
                     $update_goods_storage_arr[$groudstr]['goods_number_sum']=$update_goods_storage_arr[$groudstr]['goods_number_sum']+$v1['the_warehouse_num'];
                 }else{
                     $update_goods_storage_arr[$groudstr]['goods_number_sum']=$v1['the_warehouse_num'];
                 }
               if( $update_goods_storage_arr[$groudstr]['order_id_str']){
                    $update_goods_storage_arr[$groudstr]['order_id_str']=$update_goods_storage_arr[$groudstr]['order_id_str'].$val['batch_sn'].',';
                }else{
                    $update_goods_storage_arr[$groudstr]['order_id_str']=$val['batch_sn'].',';
                }
             }
        }
        if(count($update_goods_storage_arr)>0){
                $goods_freeze_record_mod=M('goods_freeze_record');
                $source_no=$this->get_batch_sn('PD');
                foreach ($update_goods_storage_arr as $k=>$v){
                    $goods_storage=$this->get_warehous_goods($v['wid'],$v['goods_id']);
                    if($goods_storage){
                        $goods_storage_id=$goods_storage['id'];
                    }else{
                        $goods_storage_id=0;
                    }
                   //根据订单商品修改冻结数统计，来进行修改 
                    $this->where(array('goods_id'=>$v['goods_id'],'wid'=>$v['wid']))->save(array('freeze_num'=>$v['goods_number_sum']));
                    $data_freeze=array(
                        'real_num'=>0,
                        'defective_num'=>0,
                        'operation_userid'=>0,
                        'operation_addtime'=>gmtime(),
                        'record_type'=>13,
                        'remark'=>'该商品ID('.$v['goods_id'].')分别因订单ID或者调仓来源单号('.$v[order_id_str].')的记录异常，进行冻结库存调整',
                        'average_userid'=>0,
                        'goods_storage_id'=>$goods_storage_id,
                        'wid'=>$v['wid'],
                        'goods_id'=>$v['goods_id'],
                        'goods_sn'=>$v['goods_sn'],
                        'goods_name'=>$v['goods_name'],
                        'freeze_num'=>$v['goods_number_sum'],
                        'frozen_num'=>$v['goods_number_sum'],
                        'source_no'=>$source_no,
                        
                    );
                    //生成冻结商品出入库记录
                    $goods_freeze_record_mod->add($data_freeze);
                }
                // 处理当订单收货确认后，冻结库存依旧为负时，将该商品冻结库存归0
                $goods_freeze_record_where='gs.freeze_num<0';
                if($goods_id && $wid){
                    $goods_freeze_record_where.=' AND gs.wid='.$wid.' AND gs.goods_id='.$goods_id;
                }
                $goods_freeze_record=M('goods_freeze_record')->alias('gfr')
                                    ->field('DISTINCT(gs.goods_id),gs.goods_sn,gs.wid,gs.goods_name,gs.freeze_num')
                                    ->join(C ( 'DB_PREFIX' ) .'goods_storage as gs ON gs.id=gfr.goods_storage_id')
                                    ->where($goods_freeze_record_where)
                                    ->select();
                if($goods_freeze_record){
                    foreach ($goods_freeze_record as $k=>$v){
                        $goods_storage=$this->get_warehous_goods($v['wid'],$v['goods_id']);
                        if($goods_storage){
                            $goods_storage_id=$goods_storage['id'];
                        }else{
                            $goods_storage_id=0;
                        }
                        //根据订单商品修改冻结数统计，来进行修改
                        $this->where(array('goods_id'=>$v['goods_id'],'wid'=>$v['wid']))->save(array('freeze_num'=>0));
                        $data_freeze=array(
                            'real_num'=>0,
                            'defective_num'=>0,
                            'operation_userid'=>0,
                            'operation_addtime'=>gmtime(),
                            'record_type'=>13,
                            'remark'=>'该商品ID('.$v['goods_id'].')有负数记录异常，进行冻结库存清零调整',
                            'average_userid'=>0,
                            'goods_storage_id'=>$goods_storage_id,
                            'wid'=>$v['wid'],
                            'goods_id'=>$v['goods_id'],
                            'goods_sn'=>$v['goods_sn'],
                            'goods_name'=>$v['goods_name'],
                            'freeze_num'=>0,
                            'frozen_num'=>0,
                            'source_no'=>$source_no,
                    
                        );
                        //生成冻结商品出入库记录
                        $goods_freeze_record_mod->add($data_freeze);
                    }
                }
                return true;
            }else{
                return false;
            }
    }
    
   public function  system_freeze_pandian_confirm($goods_id=0,$wid=0){
       ini_set('max_execution_time', '0');
       set_time_limit(0);
       //检查冻结记录表中，类型为商品下单、是否有过收货确认。若只有商品下单，下单七天之内，却没有收货确认记录，进行处理冻余
       $gfrwhere="record_type=4 and source_no!='' and operation_addtime >1477190668";
       if($goods_id && $wid){
           $gfrwhere.=' and goods_id='.$goods_id.' and wid='.$wid;
       }
       $goods_freeze_record_mod=M('goods_freeze_record');
       $source_no=$this->get_batch_sn('PD');
       $gfrlist=$goods_freeze_record_mod->field('id,wid,goods_id,goods_sn,goods_name,freeze_num,operation_addtime,source_no,record_type')->where($gfrwhere)->select();
       if($gfrlist){
           foreach ($gfrlist as $key=>$val){
               $goodscount=M('order_info')->alias('oi')
               ->field('og.goods_id,og.goods_sn,og.goods_name,og.goods_number,oi.wid,og.order_id,oi.order_status')
               ->join(C ( 'DB_PREFIX' ) .'order_goods as og on oi.order_id=og.order_id')
               ->where("oi.order_sn='".$val['source_no']."' and oi.wid=".$val['wid'].' and og.goods_id='.$val['goods_id'].' and (oi.order_status NOT IN (2,3,4))')
               ->count();
               if($goodscount<=0){
                   continue;
               }
               $operation_addtime=$val['operation_addtime']+3600*24*7;//获取未来七天内时间
               $gfrres=$goods_freeze_record_mod->where(array('record_type'=>array('in','5,6,9,12'),'source_no'=>$val['source_no'],'goods_id'=>$val['goods_id'],'wid'=>$val['wid']))->find();
               if(!$gfrres){
       
                   $goods_storage=$this->get_warehous_goods($val['wid'],$val['goods_id']);
                   if($goods_storage){
                       $goods_storage_id=$goods_storage['id'];
                       $freeze_num=$goods_storage['freeze_num']-$val['freeze_num'];
                       //根据订单商品修改冻结数统计，来进行修改
                       $this->where(array('goods_id'=>$val['goods_id'],'wid'=>$val['wid']))->save(array('freeze_num'=>$freeze_num));
                       $data_freeze=array(
                           'real_num'=>0,
                           'defective_num'=>0,
                           'operation_userid'=>0,
                           'operation_addtime'=>gmtime(),
                           'record_type'=>13,
                           'remark'=>'该商品ID('.$val['goods_id'].')分别因商品下单，未来七天内都未按收货确认。对应订单号('.$val['source_no'].')的记录异常，进行冻结库存调整',
                           'average_userid'=>0,
                           'goods_storage_id'=>$goods_storage_id,
                           'wid'=>$val['wid'],
                           'goods_id'=>$val['goods_id'],
                           'goods_sn'=>$val['goods_sn'],
                           'goods_name'=>$val['goods_name'],
                           'freeze_num'=>$val['freeze_num'],
                           'frozen_num'=>$freeze_num,
                           'source_no'=>$source_no,
       
                       );
                       //生成冻结商品出入库记录
                       $goods_freeze_record_mod->add($data_freeze);
                   }
               }
           }
           return true;
       }else{
           return false;
       }
   }
    
   /*
    * 生成批次号
    * */
   private function get_batch_sn($prefix){
       /* 选择一个随机的方案 */
       mt_srand((double) microtime() * 1000000);
       
       return $prefix.date('YmdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
   }

    /*
      * 核实实际库存出入库记录是否有商品下单记录-的操作，若有则返回true，否则返回false
      * */
    public function verify_gsr($wid=0,$goods_id=0,$source_no=''){
        if($wid && $goods_id && !empty($source_no)){
            $gsrdata=M('goods_storage_record')->field('id')->where(array('wid'=>$wid,'goods_id'=>$goods_id,'record_type'=>10,'source_no'=>$source_no))->find();
            if($gsrdata['id']>0){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    /*
     * 核实冻结库存出入库记录是否有商品下单记录+的操作，若有则返回true，否则返回false
     * */
    public function verify_gfr($wid=0,$goods_id=0,$source_no=''){
        if($wid && $goods_id && !empty($source_no)){
            $gfrdata=M('goods_freeze_record')->field('id')->where(array('wid'=>$wid,'goods_id'=>$goods_id,'record_type'=>4,'source_no'=>$source_no))->find();
            if($gfrdata['id']>0){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    /**
     * @author Jerry
     * @param int $goods_id
     * @param int $startTime
     * @param int $endTime
     * @param bool $isBuyNow
     * @return mixed
     */
    public function findGoodsPromoteOrderNumber($goods_id = 0, $startTime = 0, $endTime = 0, $isBuyNow = false)
    {
        $where = array(
            'o.add_time'    =>  array(array('LT', $endTime), array('EGT', $startTime)),
            'og.goods_id'  =>  $goods_id,
            'o.pay_status'  =>  array('NEQ', 0),
            'o.shipping_status'=> array(array('NEQ', 2), array('NEQ', 3)),
        );

        if ($isBuyNow) {
            $where['og.giving'] = 5;
        }
        else{
            $where['og.giving'] = 4;
        }

        $join = 'left join sdx_order_goods as og on o.order_id = og.order_id';

         $data = $this->table('sdx_order_info')
                        ->alias('o')
                        ->where($where)
                        ->join($join)
                        ->sum('og.goods_number');

         return $data;
    }

}